import requests
import json
import re
import time
from config import DEEPSEEK_API_KEY, DEEPSEEK_API_URL

class APIRetryExhaustedError(Exception):
    """API重试次数耗尽异常"""
    pass

def deepseek_resplit_paragraph(paragraph, language):
    """使用DeepSeek大模型重新分句单个段落"""
    headers = {"Authorization": f"Bearer {DEEPSEEK_API_KEY}", "Content-Type": "application/json"}

    # 根据语言选择提示语
    prompt = f"请将以下{'中文' if language == 'chinese' else '英文'}段落按句子分割（保留原格式，有标点符号错误也按标点分割），输出为JSON列表:\n\n{paragraph}"

    data = {
        "model": "deepseek-chat",
        "messages": [{"role": "user", "content": prompt}],
        "temperature": 0.1
    }

    try:
        response = requests.post(DEEPSEEK_API_URL, headers=headers, json=data, timeout=60)
        response.raise_for_status()
        response_data = response.json()

        if 'choices' in response_data and response_data['choices']:
            content = response_data['choices'][0]['message']['content'].strip()

            try:
                sentences = json.loads(content)
                if isinstance(sentences, list):
                    return "".join(sentences) if language == "chinese" else " ".join(sentences)
            except json.JSONDecodeError:
                match = re.search(r'\[.*\]', content, re.DOTALL)
                if match:
                    try:
                        sentences = json.loads(match.group(0))
                        if isinstance(sentences, list):
                            return "".join(sentences) if language == "chinese" else " ".join(sentences)
                    except:
                        pass
        return paragraph  # 失败时返回原文
    except Exception as e:
        print(f"DeepSeek重分句API调用失败: {str(e)}")
        return paragraph

def test_api_connection():
    """测试DeepSeek API连接"""
    print("测试API连接...")
    headers = {
        "Authorization": f"Bearer {DEEPSEEK_API_KEY}",
        "Content-Type": "application/json"
    }
    try:
        # 使用简单提示测试API
        test_prompt = "请回答'是'或'否': 1+1=2 是否正确？"
        data = {
            "model": "deepseek-chat",
            "messages": [{"role": "user", "content": test_prompt}],
            "max_tokens": 2,
            "temperature": 0.1
        }
        response = requests.post(DEEPSEEK_API_URL, headers=headers, json=data, timeout=10)
        response.raise_for_status()

        if response.status_code == 200:
            result = response.json()
            if 'choices' in result and len(result['choices']) > 0:
                answer = result['choices'][0]['message']['content'].strip().lower()
                print(f"API测试成功，返回: '{answer}'")
                return True

        print(f"API测试失败，响应: {response.text}")
        return False
    except Exception as e:
        print(f"API测试失败: {e}")
        return False

def compare_paragraphs_with_deepseek(para_cn, para_en):
    """使用DeepSeek API比较两个段落内容是否对应"""
    headers = {
        "Authorization": f"Bearer {DEEPSEEK_API_KEY}",
        "Content-Type": "application/json"
    }

    # 截断长段落以避免API限制
    max_length = 3000  # 根据模型上下文窗口调整
    truncated_cn = para_cn[:max_length] + ("..." if len(para_cn) > max_length else "")
    truncated_en = para_en[:max_length] + ("..." if len(para_en) > max_length else "")

    prompt = f"""
请严格评估以下两个段落是否表达相同的内容。请基于以下核心标准判断：

### 核心评估标准：
1. **内容完整性**：
   - 是否有任何一方遗漏关键事实、数据或观点

2. **段落对应关系**：
   - 段落边界是否合理对应

3. **实质性差异**：
   - 是否存在关键信息不一致

### 输出要求：
仅回答"是"或"否"，不要提供解释

### 段落1 (中文):
{truncated_cn}

### 段落2 (英文):
{truncated_en}

### 问题：
两个段落是否完整表达了相同的内容？（即没有内容缺失或多余）
"""

    data = {
        "model": "deepseek-chat",  # 或 "deepseek-r1"
        "messages": [{"role": "user", "content": prompt}],
        "temperature": 0.1,
        "max_tokens": 10,  # 减小这个值
        "stop": ["\n"]
    }

    max_retries = 3
    retry_delay = 10  # 秒

    for attempt in range(max_retries):
        try:
            print(f"发送API请求 (尝试 {attempt + 1}/{max_retries})...")
            response = requests.post(DEEPSEEK_API_URL, headers=headers,
                                     json=data, timeout=60)
            response.raise_for_status()

            # 检查API响应是否有效
            if response.status_code != 200:
                print(f"API错误响应: {response.text}")
                raise ValueError(f"API返回非200状态码: {response.status_code}")

            result = response.json()
            print(f"API响应: {json.dumps(result, indent=2, ensure_ascii=False)}")

            # 检查响应结构是否包含所需数据
            if 'choices' not in result or len(result['choices']) == 0:
                raise ValueError("API响应中缺少'choices'字段")

            # 获取消息内容
            if 'message' in result['choices'][0]:
                message_content = result['choices'][0]['message']['content']
            else:
                # 兼容旧版响应格式
                message_content = result['choices'][0]['text']

            answer = message_content.strip().lower()
            print(f"API原始回答: '{answer}'")

            # 验证响应内容是否有效
            if "是" in answer:
                return True
            elif "否" in answer:
                return False
            else:
                raise ValueError(f"API返回无效响应: '{answer}'")

        except requests.exceptions.HTTPError as e:
            status_code = e.response.status_code if e.response else "未知"
            print(f"HTTP错误 (状态码 {status_code}): {e}")

            # 处理速率限制
            if status_code == 429:
                retry_after = int(e.response.headers.get('Retry-After', 30))
                print(f"达到速率限制，{retry_after}秒后重试...")
                time.sleep(retry_after)
                continue

            if attempt < max_retries - 1:
                print(f"{retry_delay}秒后重试...")
                time.sleep(retry_delay)
            else:
                raise APIRetryExhaustedError(f"API重试次数耗尽: {str(e)}")

        except (requests.exceptions.RequestException, ValueError) as e:
            print(f"API调用错误 (尝试 {attempt + 1}/{max_retries}): {e}")
            if attempt < max_retries - 1:
                print(f"{retry_delay}秒后重试...")
                time.sleep(retry_delay)
            else:
                raise APIRetryExhaustedError(f"API重试次数耗尽: {str(e)}")
        except Exception as e:
            print(f"未知错误: {e}")
            if attempt < max_retries - 1:
                print(f"{retry_delay}秒后重试...")
                time.sleep(retry_delay)
            else:
                raise APIRetryExhaustedError(f"API重试次数耗尽: {str(e)}")

    # 如果所有尝试都失败，返回降级处理结果
    len_diff = abs(len(para_cn) - len(para_en)) / max(len(para_cn), len(para_en))
    return len_diff < 0.7